import {
  HttpException,
  HttpStatus,
  Injectable,
  ServiceUnavailableException,
} from '@nestjs/common';
import { CreatePromotionDto } from '../dto/promotion/create-promotion.dto';
import { UpdatePromotionDto } from '../dto/promotion/update-promotion.dto';
import { Promotion } from '../entities/promotion.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ListPromotionDto } from '../dto/promotion/list-promotion.dto';
import { ResMsg } from 'src/utils/public.enum';
import { GoodsService } from './goods.service';

@Injectable()
export class PromotionService {
  constructor(
    @InjectRepository(Promotion, 'shop')
    private readonly promotionRepository: Repository<Promotion>,
    private readonly goodsService: GoodsService,
  ) {}

  async create(createPromotionDto: CreatePromotionDto) {
    const isExitGoods = await this.findOneByGoodsIs(
      +createPromotionDto.goodsId,
    );
    if (isExitGoods) {
      if (isExitGoods) {
        throw new HttpException(
          {
            status: HttpStatus.BAD_REQUEST,
            error: '当前商品已存在',
          },
          HttpStatus.BAD_REQUEST,
        );
      }
      // throw new HttpException('当前促销商品已经存在', HttpStatus.BAD_REQUEST);
      // throw new BadRequestException('Something bad happened', { cause: new Error(), description: 'Some error description' })
    }
    const row = new Promotion(createPromotionDto);
    const result = await this.promotionRepository.save(row);

    const goodsDBRow = await this.goodsService.findOne(
      +createPromotionDto.goodsId,
    );
    const goodsPromotion = await this.goodsService.update(
      +createPromotionDto.goodsId,
      { ...goodsDBRow, isPromotion: 1 },
    );
    if (result && goodsPromotion === ResMsg.Success) {
      return ResMsg.Success;
    }
    return ResMsg.Fail;
  }

  async findAll(listPromotionDto: ListPromotionDto) {
    try {
      const {
        id = null,
        title = '',
        desc = '',
        goodsId = null,
        categoryId = null,
      } = listPromotionDto.queryDto;
      const queryBuilder =
        this.promotionRepository.createQueryBuilder('promotion');

      if (id) {
        queryBuilder.where('promotion.id = :id', { id });
      }

      if (goodsId) {
        queryBuilder.andWhere('promotion.goods_id = :goodsId', { goodsId });
      }

      if (categoryId) {
        queryBuilder.andWhere('promotion.category_id = :categoryId', {
          categoryId,
        });
      }

      queryBuilder
        .andWhere('promotion.is_delete = :isDelete', { isDelete: 1 })
        .andWhere('promotion.title LIKE :title AND promotion.desc LIKE :desc', {
          title: `%${title}%`,
          desc: `%${desc}%`,
        });

      const [list, total] = await queryBuilder
        .orderBy('promotion.modify_time', 'DESC')
        .skip(
          (listPromotionDto.pageDto.pageNo - 1) *
            listPromotionDto.pageDto.pageSize,
        )
        .take(listPromotionDto.pageDto.pageSize)
        .getManyAndCount();

      return {
        list,
        total,
        ...listPromotionDto.pageDto,
      };
    } catch (e) {
      throw new ServiceUnavailableException();
    }
  }

  async findOne(id: number) {
    try {
      const res = await this.promotionRepository.findOneBy({
        id,
        isDelete: 1,
      });
      return res;
    } catch (e) {
      throw new ServiceUnavailableException();
    }
  }

  async update(id: number, updatePromotionDto: UpdatePromotionDto) {
    try {
      const dbRow = await this.findOne(id);
      if (dbRow) {
        const data = {
          ...dbRow,
          ...updatePromotionDto,
        };
        const result = this.promotionRepository.save(data);
        if (result) {
          return ResMsg.Success;
        }
        return ResMsg.Fail;
      } else {
        throw new HttpException('当前数据不存在！', HttpStatus.BAD_REQUEST);
      }
    } catch (e) {
      throw new ServiceUnavailableException();
    }
  }

  async remove(id: number) {
    try {
      const dbRow = await this.findOne(id);
      if (dbRow) {
        const data = {
          ...dbRow,
          isDelete: -1,
        };
        const result = this.promotionRepository.save(data);
        if (result) {
          return ResMsg.Success;
        }
        return ResMsg.Fail;
      } else {
        throw new HttpException('当前数据不存在！', HttpStatus.BAD_REQUEST);
      }
    } catch (e) {
      throw new ServiceUnavailableException();
    }
  }

  async findOneByGoodsIs(goodsId: number) {
    try {
      const res = await this.promotionRepository.findOneBy({
        goodsId,
        isDelete: 1,
      });
      return res;
    } catch (e) {
      throw new ServiceUnavailableException();
    }
  }
}
